package cn.zyjblogs.starter.sms.provider.aliyun;

import cn.zyjblogs.starter.common.utils.collect.Lists;
import cn.zyjblogs.starter.sms.common.SmsCommon;
import cn.zyjblogs.starter.sms.common.SmsEnum;
import cn.zyjblogs.starter.sms.common.SmsRequest;
import cn.zyjblogs.starter.sms.common.SmsResponse;
import cn.zyjblogs.starter.sms.config.SmsProperties;
import cn.zyjblogs.starter.sms.exception.SmsRuntimeException;
import cn.zyjblogs.starter.sms.provider.AbstractSmsGranter;
import cn.zyjblogs.starter.sms.provider.SmsGranter;
import com.alibaba.fastjson2.JSON;
import com.aliyun.sdk.service.dysmsapi20170525.AsyncClient;
import com.aliyun.sdk.service.dysmsapi20170525.models.SendSmsRequest;
import com.aliyun.sdk.service.dysmsapi20170525.models.SendSmsResponse;

import java.util.List;
import java.util.concurrent.CompletableFuture;

/**
 * @author zhuyijun
 */
public class AliSmsHandleGranter extends AbstractSmsGranter {
    private static final SmsEnum  TYPE_NAME = SmsEnum.ALI_SMS;
    private final AsyncClient aliSyncClient;
    private final SmsProperties.AliyunSmsProperties aliyunSmsProperties;

    public AliSmsHandleGranter(AsyncClient aliSyncClient, SmsProperties.AliyunSmsProperties aliyunSmsProperties, SmsEnum smsEnum) {
        super(smsEnum);
        this.aliSyncClient = aliSyncClient;
        this.aliyunSmsProperties = aliyunSmsProperties;
        if (aliyunSmsProperties.getMaxSize() == null || aliyunSmsProperties.getMaxSize() < 100) {
            aliyunSmsProperties.setMaxSize(200);
        }
    }

    public AliSmsHandleGranter(AsyncClient aliSyncClient, SmsProperties.AliyunSmsProperties aliyunSmsProperties) {
        super(TYPE_NAME);
        this.aliSyncClient = aliSyncClient;
        this.aliyunSmsProperties = aliyunSmsProperties;
    }

    /**
     * 短信发送 ，手机号为多个以逗号隔开
     *
     * @param phones
     * @param smsRequest
     * @return
     */
    @Override
    public SmsResponse sendSms(List<String> phones, SmsRequest smsRequest) {
        Object o = smsRequest.getParamsMap().get(SmsCommon.TEMPLATE_PARAM);
        if (o == null) {
            throw new SmsRuntimeException("参数不能为空");
        }
        try {
            String templateCode = smsRequest.getTemplateCode();
            String templateParam = JSON.toJSONString(o);
            List<List<String>> partition = Lists.partition(phones, aliyunSmsProperties.getMaxSize());
            partition.forEach(phoneList -> {
                SendSmsRequest sendSmsRequest = SendSmsRequest.builder()
                        .phoneNumbers(String.join(",", phoneList))
                        .signName(smsRequest.getSignName())
                        .templateCode(templateCode)
                        .templateParam(templateParam)
                        .build();
                CompletableFuture<SendSmsResponse> sendSmsResponseCompletableFuture = aliSyncClient.sendSms(sendSmsRequest);
                CompletableFuture.allOf(sendSmsResponseCompletableFuture);
                System.out.printf(JSON.toJSONString(sendSmsResponseCompletableFuture.join().getBody()));
            });
            return SmsResponse.builder()
                    .code("OK")
                    .message("发送成功")
                    .build();
        } catch (Exception e) {
            throw new SmsRuntimeException("发送失败");
        }
    }

    @Override
    public SmsResponse sendSms(String phone, SmsRequest smsRequest) {
        Object o = smsRequest.getParamsMap().get(SmsCommon.TEMPLATE_PARAM);
        if (o == null) {
            throw new SmsRuntimeException("参数不能为空");
        }
        try {
            SendSmsRequest sendSmsRequest = SendSmsRequest.builder()
                    .phoneNumbers(phone)
                    .signName(smsRequest.getSignName())
                    .templateCode(smsRequest.getTemplateCode())
                    .templateParam(JSON.toJSONString(o))
                    .build();
            CompletableFuture<SendSmsResponse> sendSmsResponseCompletableFuture = aliSyncClient.sendSms(sendSmsRequest);
            CompletableFuture.allOf(sendSmsResponseCompletableFuture);
            SendSmsResponse join = sendSmsResponseCompletableFuture.join();
            return SmsResponse.builder()
                    .code("OK")
                    .message(join.getBody().getMessage())
                    .data(join)
                    .build();
        } catch (Exception e) {
            throw new SmsRuntimeException("发送失败");
        }
    }

    @Override
    public SmsGranter getGranter(SmsEnum typeName) {
        if (TYPE_NAME.equals(typeName)) {
            return this;
        }
        return null;
    }
}
